package com.kcht.rd30.service.impl;

import com.kcht.rd30.dto.DetectionReport;
import com.kcht.rd30.dto.ReaderStatus;
import com.kcht.rd30.entity.AbnormalDetectionEntity;
import com.kcht.rd30.mapper.IAbnormalDetectionMapper;
import com.kcht.rd30.utils.JsonUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.ibatis.exceptions.PersistenceException;
import org.zeromq.SocketType;
import org.zeromq.ZContext;
import org.zeromq.ZMQ;
import uhf_msg.Uhf;

import java.net.URI;
import java.util.Objects;

@Slf4j
public class AbnormalDetectionHandler implements Runnable {
    private Integer duration;
    private URI reportUrl;
    private IAbnormalDetectionMapper abnormalDetectionMapper;
    private String ip;
    private int port = 10001;
    private Boolean isClose = false;
    private static Integer recvTimeout = 5000;
    //设置响应超时，连接超时
    private RequestConfig config = RequestConfig.custom().setSocketTimeout(2000).setConnectTimeout(2000).build();

    public AbnormalDetectionHandler(String ip, String reportUrl, Integer duration, IAbnormalDetectionMapper abnormalDetectionMapper) {
        try {
            this.ip = ip;
            this.reportUrl = new URI(reportUrl);
            this.duration = duration;
            this.abnormalDetectionMapper = abnormalDetectionMapper;
            new Thread(this).start();
            log.info("{} ---> 开启异常检测线程", ip);
        } catch (Exception e) {
            log.error("{} ---> 生成异常检测处理器失败", ip);
            log.error(e.getMessage());
        }
    }

    @Override
    public void run() {
        while (!isClose) {
            try {
                AbnormalDetectionEntity ad = abnormalDetectionMapper.findByIp(ip);
                detection(ad);
            } catch (Exception e) {
                log.error("未知异常",e);
            }
            try {
                Thread.sleep(duration * 1000);
            } catch (InterruptedException e) {
                log.error("sleep中止异常",e);
            }
        }
        log.info("{} ---> 关闭异常检测线程", ip);
    }

    public void closeThread() {
        this.isClose = true;
    }

    private void detection(AbnormalDetectionEntity ad) {
        try (ZContext context = new ZContext()) {
            try (ZMQ.Socket req = context.createSocket(SocketType.REQ)) {
                req.setLinger(0);
                req.setHeartbeatTimeout(recvTimeout);
                req.setReceiveTimeOut(recvTimeout);
                req.setSendTimeOut(recvTimeout);
                req.connect("tcp://" + ip + ":" + port);
                Uhf.uhf_request request = Uhf.uhf_request.getDefaultInstance();
                request= request.toBuilder()
                        .setType(Uhf.uhf_request.HeadType.calcSwr)
                        .build();
                req.send(request.toByteArray());
                byte[] recv = req.recv();
                if(recv!=null){
                    final Uhf.uhf_response.CalcSwrResponse swrResponse = Uhf.uhf_response.parseFrom(recv).getSwrResponse();
                    int [] swrs=new int[]{swrResponse.getSwr1(),swrResponse.getSwr2(),swrResponse.getSwr3(),swrResponse.getSwr4()};
                    int maxSwr=0;
                    for (int swr : swrs) {
                        if(swr!=10000&&swr>maxSwr){
                            maxSwr=swr;
                        }
                    }
                    if(maxSwr>=ad.getSwrBoundary()){
                        log.error("驻波比异常 ---> "+maxSwr);
                        if(maxSwr>ad.getSwrMaxValue()){
                            ad.setSwrMaxValue(maxSwr);
                            abnormalDetectionMapper.updateById(ad);
                        }
                        sendDetectionHandler(DetectionReport.builder()
                                .code(ReaderStatus.驻波比异常.ordinal())
                                .ip(ip)
                                .msg(ReaderStatus.驻波比异常+","+maxSwr+"驻波比超过临界值")
                                .build());
                    }else{
                        log.info("{} ---> 驻波比正常",ip);
                        sendDetectionHandler(DetectionReport.builder()
                                .code(ReaderStatus.正常.ordinal())
                                .ip(ip)
                                .msg(ReaderStatus.正常.toString())
                                .build());
                    }
                }else{
                    throw new RuntimeException(ip+" ---> "+ReaderStatus.网络异常.toString());
                }
            }
        }catch (PersistenceException e){
            log.error("持久化异常",e);
        }catch (Exception e) {
            log.error("网络异常",e);
            sendDetectionHandler(DetectionReport.builder()
                    .code(ReaderStatus.网络异常.ordinal())
                    .ip(ip)
                    .msg(ReaderStatus.网络异常.toString())
                    .build());
        }
    }


    private void sendDetectionHandler(DetectionReport dr) {
        try (CloseableHttpClient client = HttpClientBuilder
                .create()
                .build()) {
            HttpPost post = new HttpPost();
            post.setConfig(config);
            post.setURI(reportUrl);
            post.setHeader("content-type","application/json");
            post.setEntity(new StringEntity(Objects.requireNonNull(JsonUtils.objectToJson(dr)), "utf-8"));
            try (CloseableHttpResponse response = client.execute(post)) {
                int statusCode = response.getStatusLine().getStatusCode();
                if (statusCode > 199 && statusCode < 300) {
                    log.info("{} ---> 异常检测结果成功上报到 ---> {}", ip,reportUrl);
                } else {
                    log.error("{} ---> 异常检测结果上报失败 ---> {}，错误码 ---> {}", ip,reportUrl, statusCode);
                }
            }
        } catch (Exception e) {
            log.error("发送失败，请确保{}可达",reportUrl);
        }
    }
}
